package com.coocaa.x.uipackage.dialog;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ViewFlipper;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.Cache;
import com.coocaa.x.framework.utils.LiteHandlerThread;
import com.coocaa.x.uipackage.R;
import com.coocaa.x.uipackage.SkinManager;
import com.coocaa.x.uipackage.ThemeDialog;
import com.coocaa.x.uipackage.utils.FrescoUtils;
import com.coocaa.x.uipackage.widget.CoocaaDraweeView;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by lu on 15-8-15.
 */
public class ImageGallery extends ThemeDialog {
    public static final Animation ANIMATION_FADE_IN = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.fade_in);
    public static final Animation ANIMATION_FADE_OUT = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.fade_out);


    public static final Animation ANIMATION_IN_UP_DOWN = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.in_updown);
    public static final Animation ANIMATION_IN_DOWN_UP = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.in_downup);
    public static final Animation ANIMATION_IN_LEFT_RIGHT = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.in_leftright);
    public static final Animation ANIMATION_IN_RIGHT_LEFT = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.in_rightleft);

    public static final Animation ANIMATION_OUT_UP_DOWN = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.out_updown);
    public static final Animation ANIMATION_OUT_DOWN_UP = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.out_downup);
    public static final Animation ANIMATION_OUT_LEFT_RIGHT = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.out_leftright);
    public static final Animation ANIMATION_OUT_RIGHT_LEFT = AnimationUtils.loadAnimation(CoocaaApplication.getContext(), R.anim.out_rightleft);


    public static class ImageUri {
        public Uri previewUri, contentUri;
        public int defaultResID = -1;

        public ImageUri(Uri uri) {
            this.previewUri = uri;
            this.contentUri = uri;
        }

        public ImageUri(Uri previewUri, Uri contentUri) {
            this.previewUri = previewUri;
            this.contentUri = contentUri;
        }

        public ImageUri(int defaultResID, Uri previewUri, Uri contentUri) {
            this.defaultResID = defaultResID;
            this.previewUri = previewUri;
            this.contentUri = contentUri;
        }

        @Override
        public boolean equals(Object o) {
            if (!ImageUri.class.isInstance(o))
                return false;
            ImageUri oo = (ImageUri) o;
            try {
                return oo.contentUri.equals(contentUri);
            } catch (Exception e) {
                return false;
            }
        }
    }

    public static class ImageGalleryController extends FrameLayout {
        public ImageGalleryController() {
            super(CoocaaApplication.getContext());
            setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            setFocusableInTouchMode(false);
            setFocusable(false);
            onCreate();
        }

        protected void onCreate() {

        }

        public Animation getInAnimation() {
            return null;
        }

        public Animation getOutAnimation() {
            return null;
        }

        public void onImageInit(ImageGallery gallery, ImageUri current, List<ImageUri> uris, Bundle bundle) {
        }

        public void onImageSwitchStart(ImageGallery gallery, ImageUri from, ImageUri to, List<ImageUri> uris, Bundle bundle) {
        }

        public void onImageSwitchEnd(ImageGallery gallery, ImageUri current, List<ImageUri> uris, Bundle bundle) {
        }

        private Timer timer = null;

        public final void show(long time) {
            synchronized (this) {
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                } else {
                    setVisibility(View.VISIBLE);
                    Animation in = getInAnimation();
                    if (in != null) {
                        in.setFillAfter(true);
                        startAnimation(in);
                    }
                }
                if (time > 0) {
                    timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            LiteHandlerThread.postOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    hide();
                                }
                            });
                        }
                    }, time);
                }
            }
        }

        public final void hide() {
            synchronized (this) {
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
            }
            Animation out = getOutAnimation();
            if (out != null) {
                out.setFillAfter(true);
                startAnimation(out);
            } else
                setVisibility(View.GONE);
        }
    }

    public static interface ImageGalleryListener {
        void onImageGalleryCreate(ImageGallery gallery, Bundle bundle);

        void onImageGalleryStop(ImageGallery gallery, Bundle bundle);

        boolean onImageGalleryKeyDown(ImageGallery gallery, int keyCode, Bundle bundle);

        void onImageClick(ImageGallery gallery, ImageUri uri, Bundle bundle);
    }

    private FrameLayout root = null;
    private ViewFlipper viewFlipper = null;
    private ImageGalleryListener listener = null;
    private ImageGalleryController controller = null;
    private Cache<String, ImageGalleryView> viewsMap = new Cache<String, ImageGalleryView>();
    private List<ImageUri> urisList = new ArrayList<ImageUri>();
    private Bundle mBundle = null;

    private static class ImageGalleryView extends FrameLayout {
        private CoocaaDraweeView v = null;
        private ImageUri mUri = null;

        public ImageGalleryView(Context context, ImageUri uri) {
            super(context);
            v = new CoocaaDraweeView(context);
            v.setFocusable(false);
            v.setFocusableInTouchMode(false);
            if (uri.defaultResID != -1)
                v.getHierarchy().setPlaceholderImage(uri.defaultResID);
            addView(v);
            setFocusable(false);
            setFocusableInTouchMode(false);
            setLayoutParams(new ViewGroup.LayoutParams(CoocaaApplication.Div(1920), CoocaaApplication.Div(1080)));
            mUri = uri;
        }

        public CoocaaDraweeView getV() {
            return v;
        }

        public ImageUri getUri() {
            return mUri;
        }
    }

    public ImageGallery(Context c) {
        super(c, R.style.style_dialog_full_screen);
        getWindow().setLayout(CoocaaApplication.Div(1920), CoocaaApplication.Div(1080));
    }

    public void show(Bundle bundle) {
        mBundle = bundle;
        super.show();
    }

    @Override
    public void show() {
        mBundle = null;
        super.show();
    }

    public void setImageGalleryListener(ImageGalleryListener l) {
        listener = l;
    }

    public void setImageGalleryController(ImageGalleryController controller) {
        this.controller = controller;
    }

    public synchronized void loadImageSource(final List<ImageUri> uris, final int showIndex) {
        Runnable run = new Runnable() {
            @Override
            public void run() {
                ImageGalleryView view = null;
                synchronized (viewsMap) {
                    for (ImageUri uri : uris) {
                        if (viewsMap.containsKey(uri.contentUri.toString()))
                            removeImageSource(uri);
                        view = new ImageGalleryView(CoocaaApplication.getContext(), uri);
                        viewsMap.add(uri.contentUri.toString(), view);
                        urisList.add(uri);
                        viewFlipper.addView(view);
                        FrescoUtils.resize(view.getV(), uri.contentUri, CoocaaApplication.Div(1920), CoocaaApplication.Div(1080), uri.previewUri);
                    }
                    if (showIndex >= 0 && showIndex < viewFlipper.getChildCount())
                        viewFlipper.setDisplayedChild(showIndex);


                    if (controller != null) {
                        View v = viewFlipper.getChildAt(showIndex);
                        if (controller != null && v != null && ImageGalleryView.class.isInstance(v))
                            controller.onImageInit(ImageGallery.this, ((ImageGalleryView) v).getUri(), urisList, mBundle);

                        if (controller != null) {
                            root.addView(controller);
                            controller.show(2000);
                        }
                    }
                }
            }
        };
        LiteHandlerThread.postOnUiThread(run);
    }

    public synchronized void removeImageSource(final ImageUri uri) {
        Runnable run = new Runnable() {
            @Override
            public void run() {
                synchronized (viewsMap) {
                    if (viewsMap.containsKey(uri.contentUri.toString())) {
                        ImageGalleryView view = viewsMap.get(uri.contentUri.toString());
                        viewsMap.remove(uri.contentUri.toString());
                        for (ImageUri uri : urisList) {
                            if (uri.contentUri.equals(uri.contentUri)) {
                                urisList.remove(uri);
                                break;
                            }
                        }
                        if (view != null)
                            viewFlipper.removeView(view);
                    }
                }
            }
        };
        LiteHandlerThread.postOnUiThread(run);
    }

    public synchronized void showNext(final Animation in, final Animation out) {
        synchronized (inAnimationListener) {
            if (isInAnimation)
                return;
            isInAnimation = true;
            try {
                View from = viewFlipper.getChildAt(viewFlipper.getDisplayedChild());
                int toIndex = viewFlipper.getDisplayedChild() + 1;
                if (toIndex == viewFlipper.getChildCount())
                    toIndex = 0;
                View to = viewFlipper.getChildAt(toIndex);


                if (controller != null && from != null && ImageGalleryView.class.isInstance(from) && to != null && ImageGalleryView.class.isInstance(to)) {
                    controller.show(2000);
                    controller.onImageSwitchStart(ImageGallery.this, ((ImageGalleryView) from).getUri(), ((ImageGalleryView) to).getUri(), urisList, mBundle);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Runnable run = new Runnable() {
            @Override
            public void run() {
                if (in != null) {
                    in.setAnimationListener(inAnimationListener);
                    viewFlipper.setInAnimation(in);
                }
                if (out != null) {
                    viewFlipper.setOutAnimation(out);
                }
                viewFlipper.showNext();
            }
        };
        LiteHandlerThread.postOnUiThread(run);
    }

    public synchronized void showPrevious(final Animation in, final Animation out) {
        synchronized (inAnimationListener) {
            if (isInAnimation)
                return;
            isInAnimation = true;
            try {
                View from = viewFlipper.getChildAt(viewFlipper.getDisplayedChild());
                int toIndex = viewFlipper.getDisplayedChild() - 1;
                if (toIndex < 0)
                    toIndex = viewFlipper.getChildCount() - 1;
                View to = viewFlipper.getChildAt(toIndex);
                if (controller != null && from != null && ImageGalleryView.class.isInstance(from) && to != null && ImageGalleryView.class.isInstance(to)) {
                    controller.show(2000);
                    controller.onImageSwitchStart(ImageGallery.this, ((ImageGalleryView) from).getUri(), ((ImageGalleryView) to).getUri(), urisList, mBundle);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Runnable run = new Runnable() {
            @Override
            public void run() {
                if (in != null) {
                    in.setAnimationListener(inAnimationListener);
                    viewFlipper.setInAnimation(in);
                }
                if (out != null) {
                    viewFlipper.setOutAnimation(out);
                }
                viewFlipper.showPrevious();
            }
        };
        LiteHandlerThread.postOnUiThread(run);
    }

    @Override
    protected void onStart() {
        super.onStart();
        root = new FrameLayout(CoocaaApplication.getContext());
        root.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        root.setFocusable(false);
        root.setFocusableInTouchMode(false);

        viewFlipper = new ViewFlipper(CoocaaApplication.getContext());
        viewFlipper.setFocusable(true);
        viewFlipper.setFocusableInTouchMode(true);
        viewFlipper.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        viewFlipper.setOnClickListener(viewOnClickListener);
        viewFlipper.setOnKeyListener(viewOnKeyListener);
        SkinManager.getInstance().setBackgroundResource(viewFlipper, R.drawable.ui_sdk_app_bg);

        root.addView(viewFlipper);
        setContentView(root);

        try {
            if (listener != null)
                listener.onImageGalleryCreate(this, mBundle);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStop() {
        try {
            if (listener != null)
                listener.onImageGalleryStop(this, mBundle);
        } catch (Exception e) {
            e.printStackTrace();
        }
        root.removeAllViews();
        root = null;
        viewFlipper.removeAllViews();
        viewFlipper.setOnClickListener(null);
        viewFlipper.setOnKeyListener(null);
        viewFlipper = null;
        listener = null;
        super.onStop();
    }

    private View.OnClickListener viewOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                View view = viewFlipper.getChildAt(viewFlipper.getDisplayedChild());
                if (listener != null && view != null && ImageGalleryView.class.isInstance(view))
                    listener.onImageClick(ImageGallery.this, ((ImageGalleryView) view).getUri(), mBundle);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    private View.OnKeyListener viewOnKeyListener = new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP)
                return true;
            try {
                if (listener != null && listener.onImageGalleryKeyDown(ImageGallery.this, keyCode,
                        mBundle))
                    return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            switch (keyCode) {
                case KeyEvent.KEYCODE_BACK:
                    dismiss();
                    return true;
                default:
                    break;
            }
            return false;
        }
    };

    private boolean isInAnimation = false;

    private Animation.AnimationListener inAnimationListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            synchronized (inAnimationListener) {
                try {
                    View view = viewFlipper.getChildAt(viewFlipper.getDisplayedChild());
                    if (controller != null && view != null && ImageGalleryView.class.isInstance(view))
                        controller.onImageSwitchEnd(ImageGallery.this, ((ImageGalleryView) view).getUri(), urisList, mBundle);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                isInAnimation = false;
            }
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };
}
